/**
  ******************************************************************************
  * @file    drv_fifo.c
  * @author  zpw
  * @version V1.0
  * @date    
  * @brief   fifo支持
  ******************************************************************************
  * @attention
  *
  * 
  * 
  * 
  *
  ******************************************************************************
  */

#include "drv_fifo.h"
#include "stdlib.h"
#include "string.h"
void queue_init(QUEUE *que, uint8_t *dp, uint16_t len)
{

    if (len < 1)
        len = 1;

    que->max = len;

#if USE_MALLOC
    if (dp == NULL)
    {
        que->data = (uint8_t *)malloc(len);
    }
    else
    {
        que->data = dp;
    }
    memset(que->data, 0, sizeof(len));
		que->head = que->tail =0;
    /* 创建互斥信号量 */
    //que->xSemaphore = xSemaphoreCreateRecursiveMutex();
#else
    //静态

#endif
}

void queue_reset(QUEUE *que)
{
    que->head = que->tail = 0;
}

void queue_push(QUEUE *que, uint8_t *data, uint16_t size)
{
#if USE_LOCK
    xSemaphoreTakeRecursive(que->xSemaphore, 10);
#endif
    if (size < 1)
        return;
    for (uint16_t i = 0; i < size; i++)
    {

        que->data[que->head] = data[i];
        que->head = (que->head + 1);
        if (que->head > que->max)
            que->head -= que->max;
        if (que->head == que->tail) //非满状态
            break;
    }

#if USE_LOCK
    xSemaphoreGiveRecursive(que->xSemaphore);
#endif
}

void queue_pop(QUEUE *que, uint8_t *data)
{
#if USE_LOCK
    xSemaphoreTakeRecursive(que->xSemaphore, 10);
#endif

    if (que->tail != que->head) //非空状态
    {

        *data = que->data[que->tail];
        que->tail = (que->tail + 1);
        if (que->tail > que->tail)
            que->tail -= que->max;
    }
#if USE_LOCK

    xSemaphoreGiveRecursive(que->xSemaphore);
#endif
}

void queue_pop_data(QUEUE *que, uint8_t *data, uint16_t size)
{
#if USE_LOCK
    xSemaphoreTakeRecursive(que->xSemaphore, 10);
#endif
    if (size < 1)
        return;
    for (uint16_t i = 0; i < size; i++)
    {

        data[i] = que->data[que->tail];
        que->tail = (que->tail + 1);
        if (que->tail > que->tail)
            que->tail -= que->max;
        if (que->tail == que->head) //非空状态
        {
            break;
        }
    }

#if USE_LOCK
    xSemaphoreGiveRecursive(que->xSemaphore);
#endif
}

//重新计算尾部
void queue_calc_tail(QUEUE *que, uint8_t size)
{

#if USE_LOCK
    xSemaphoreTakeRecursive(que->xSemaphore, 10);
#endif

    que->tail = (que->tail + size);
    if (que->tail > que->tail)
        que->tail -= que->max;
#if USE_LOCK
    xSemaphoreGiveRecursive(que->xSemaphore);
#endif
}

uint16_t queue_size(QUEUE *que)
{
    uint16_t size = 0;

#if USE_LOCK
    xSemaphoreTakeRecursive(que->xSemaphore, 10);
#endif
    int s = que->head - que->tail;
    if (s >= 0)
    {
        size = s;
    }
    else
    {
        size = s + que->max;
    }

#if USE_LOCK
    xSemaphoreGiveRecursive(que->xSemaphore);
#endif

    return size;
}

// void Fifo_push(uint16_t *predata, uint16_t data, uint16_t len)
// {

//     for (int i = len - 1; i > 0; i--)
//     {
//         predata[i] = predata[i - 1];
//     }
//     predata[0] = data;
// }
